org 0x7c00

DISTANCE equ 0x80


PORT_DISK1_DATA equ 0x1f0 - DISTANCE
PORT_DISK1_ERR_FEATURE equ 0x1f1 - DISTANCE
PORT_DISK1_SECTOR_CNT equ 0x1f2 - DISTANCE
PORT_DISK1_SECTOR_LOW equ 0x1f3 - DISTANCE
PORT_DISK1_SECTOR_MID equ 0x1f4 - DISTANCE
PORT_DISK1_SECTOR_HIGH equ 0x1f5 - DISTANCE
PORT_DISK1_DEVICE equ 0x1f6 - DISTANCE
PORT_DISK1_STATUS_CMD equ 0x1f7 - DISTANCE
PORT_DISK1_ALT_STA_CTL equ 0x3f6 - DISTANCE




start:
    
    mov ax,cs
    mov ds,ax
    mov ss,ax
    mov es,ax
    mov sp,0x7c00


    mov si,msg
    call print
    

    mov byte [count],   1
    mov dword [sector] ,   0
    xor si,si
    mov si,0x8000
    call readDisk
    cmp word [0x8000],0x55aa
    jmp $
    jz jmpToLoader 
    mov si,errormsg
    call print
jmpToLoader:
    jmp 0: 0x8002

initDsikDriver:
    mov dx,PORT_DISK1_ALT_STA_CTL
    mov al,0
    out dx,al

    call waitDiskNotBusy

    mov dx,PORT_DISK1_ERR_FEATURE
    mov al,0
    out dx,al

    mov dx,PORT_DISK1_SECTOR_CNT
    mov al,[count]
    out dx,al

    mov dx,PORT_DISK1_SECTOR_LOW
    mov ebx,[sector]
    and ebx,0xff
    mov al,bl
    out dx,al

    mov dx,PORT_DISK1_SECTOR_MID
    mov ebx,[sector]
    shr ebx,8
    and ebx,0xff
    mov al,bl
    out dx,al

    mov dx,PORT_DISK1_SECTOR_HIGH
    mov ebx,[sector]
    shr ebx,16
    and ebx,0xff
    mov al,bl
    out dx,al

    mov dx,PORT_DISK1_DEVICE
    mov ebx,[sector]
    shr ebx,24
    and ebx,0xf
    or  ebx,0x0e0
    mov al,bl
    out dx,al

    call waitDiskReady

    mov dx,PORT_DISK1_STATUS_CMD
    mov al,0x20
    out dx,al



    ret




    

readDisk:
    call initDsikDriver
    call waitDiskReady
    call waitDiskReq
    mov cx,256
.read:
    cmp cx,0
    jz .readFinish
    mov dx,PORT_DISK1_DATA
    in  ax,dx
    jmp $+2
    jmp $+2
    jmp $+2
    mov word [si],ax
    add si,2
    dec cx
    jmp .read 
.readFinish:
    ret

waitDiskNotBusy:
        mov dx,PORT_DISK1_STATUS_CMD
        in al,dx
        jmp $+2; nop 直接跳转到下一行
        jmp $+2; 一点点延迟
        jmp $+2
        and al,10000000b
        jnz waitDiskNotBusy
        ret

waitDiskReady:
        mov dx,PORT_DISK1_STATUS_CMD
        in al,dx
        jmp $+2; nop 直接跳转到下一行
        jmp $+2; 一点点延迟
        jmp $+2
        and al,01000000b
        jz waitDiskReady
        ret


waitDiskReq:
    mov dx,PORT_DISK1_STATUS_CMD
    in al,dx
    jmp $+2; nop 直接跳转到下一行
    jmp $+2; 一点点延迟
    jmp $+2
    and al,00001000b
    jz waitDiskReq
    ret

print:
    mov ah,0x0e
.next:
    mov al,[si]
    cmp al,0
    jz .done
    int 0x10
    inc si
    jmp .next
.done:
    ret

break:
    xchg bx,bx
    ret

    sector dd 0x00000000 

    count db 0x00

    msg db "start boot",10,13,0

    errormsg db "load loader error",10,13,0

    times 510 -($ - $$) db 0


    dw 0xaa55